package cn.drenal.capcap.controller.forum;

import cn.dev33.satoken.annotation.SaIgnore;
import cn.dev33.satoken.stp.StpUtil;
import cn.dev33.satoken.util.SaResult;
import cn.drenal.capcap.common.Response;
import cn.drenal.capcap.entity.Artwork;
import cn.drenal.capcap.entity.ArtworkFavorite;
import cn.drenal.capcap.entity.User;
import cn.drenal.capcap.entity.UserFollow;
import cn.drenal.capcap.entity.vo.forum.ForumArtworkCardVO;
import cn.drenal.capcap.entity.vo.forum.UserProfileWithWorksVO;
import cn.drenal.capcap.mapper.ArtworkFavoriteMapper;
import cn.drenal.capcap.mapper.ArtworkMapper;
import cn.drenal.capcap.mapper.UserFollowMapper;
import cn.drenal.capcap.mapper.UserMapper;
import cn.drenal.capcap.entity.dto.UserLoginDTO;
import cn.drenal.capcap.entity.dto.UserRegisterDTO;
import cn.drenal.capcap.entity.vo.UserVO;
import cn.drenal.capcap.service.ArtworkService;
import cn.drenal.capcap.service.UserService;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import lombok.RequiredArgsConstructor;
import org.springframework.beans.BeanUtils;
import org.springframework.util.DigestUtils;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.*;

import java.nio.charset.StandardCharsets;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * 论坛用户控制器
 * 处理论坛端用户的登录、注册等功能
 */
@RestController
@RequiredArgsConstructor
@RequestMapping("/forum/user")
public class ForumUserController {

    private final UserMapper userMapper;

    private final UserFollowMapper userFollowMapper;

    private final ArtworkFavoriteMapper artworkFavoriteMapper;

    private final ArtworkService artworkService;

    private final UserService userService;
    
    private final ArtworkMapper artworkMapper;

    /**
     * 用户登录
     * 支持用户名或邮箱登录
     *
     * @param userLoginDTO 登录信息
     * @return 登录结果
     */
    @PostMapping("/login")
    public SaResult login(@RequestBody UserLoginDTO userLoginDTO) {
        // 参数校验
        if (userLoginDTO == null || userLoginDTO.getAccount() == null || userLoginDTO.getPassword() == null) {
            return SaResult.error("参数不完整");
        }

        // 构建查询条件：用户名或邮箱匹配
        LambdaQueryWrapper<User> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(User::getUsername, userLoginDTO.getAccount())
                .or()
                .eq(User::getEmail, userLoginDTO.getAccount());

        // 查询用户
        User user = userMapper.selectOne(queryWrapper);

        // 用户不存在
        if (user == null) {
            return SaResult.error("用户名或密码错误");
        }

        // 账号被禁用
        if (user.getStatus() == 0) {
            return SaResult.error("账号已被禁用");
        }

        // 账号待审核
        if (user.getStatus() == 2) {
            return SaResult.error("账号正在审核中");
        }

        // 密码校验（使用MD5加密比对）
        String encryptedPassword = DigestUtils.md5DigestAsHex(userLoginDTO.getPassword().getBytes(StandardCharsets.UTF_8));
        if (!user.getPassword().equals(encryptedPassword)) {
            return SaResult.error("用户名或密码错误");
        }

        // 登录成功，使用Sa-Token记录登录状态
        StpUtil.login(user.getId(), "forum");

        // 构建返回数据
        Map<String, Object> data = new HashMap<>();
        data.put("tokenName", StpUtil.getTokenName());
        data.put("tokenValue", StpUtil.getTokenValue());

        // 转换为VO对象，不返回敏感信息
        UserVO userVO = new UserVO();
        BeanUtils.copyProperties(user, userVO);
        data.put("userInfo", userVO);

        return SaResult.data(data);
    }

    /**
     * 用户注册
     *
     * @param userRegisterDTO 注册信息
     * @return 注册结果
     */
    @PostMapping("/register")
    public SaResult register(@RequestBody UserRegisterDTO userRegisterDTO) {
        // 参数校验
        if (userRegisterDTO == null || userRegisterDTO.getUsername() == null ||
                userRegisterDTO.getPassword() == null || userRegisterDTO.getEmail() == null) {
            return SaResult.error("参数不完整");
        }

        // 检查用户名是否已存在
        LambdaQueryWrapper<User> usernameWrapper = new LambdaQueryWrapper<>();
        usernameWrapper.eq(User::getUsername, userRegisterDTO.getUsername());
        if (userMapper.selectCount(usernameWrapper) > 0) {
            return SaResult.error("用户名已存在");
        }

        // 检查邮箱是否已存在
        LambdaQueryWrapper<User> emailWrapper = new LambdaQueryWrapper<>();
        emailWrapper.eq(User::getEmail, userRegisterDTO.getEmail());
        if (userMapper.selectCount(emailWrapper) > 0) {
            return SaResult.error("邮箱已被注册");
        }

        // 创建用户对象
        User user = new User();
        user.setUsername(userRegisterDTO.getUsername());
        user.setEmail(userRegisterDTO.getEmail());
        // 设置默认昵称为用户名
        user.setNickname(userRegisterDTO.getUsername());
        // 密码加密存储
        String encryptedPassword = DigestUtils.md5DigestAsHex(userRegisterDTO.getPassword().getBytes(StandardCharsets.UTF_8));
        user.setPassword(encryptedPassword);
        // 设置默认状态为启用
        user.setStatus(1);

        // 保存用户
        userMapper.insert(user);

        return SaResult.ok("注册成功");
    }

    /**
     * 获取当前登录用户信息
     *
     * @return 用户信息
     */
    @GetMapping("/info")
    public SaResult getUserInfo() {
        // 检查是否已登录
        if (!StpUtil.isLogin()) {
            return SaResult.error("未登录");
        }

        // 获取当前登录用户ID
        Long userId = StpUtil.getLoginIdAsLong();
        User user = userMapper.selectById(userId);

        if (user == null) {
            return SaResult.error("用户不存在");
        }

        // 转换为VO对象，不返回敏感信息
        UserVO userVO = new UserVO();
        BeanUtils.copyProperties(user, userVO);

        return SaResult.data(userVO);
    }

    /**
     * 退出登录
     *
     * @return 退出结果
     */
    @PostMapping("/logout")
    public SaResult logout() {
        StpUtil.logout();
        return SaResult.ok("退出成功");
    }

    /**
     * 检查会话状态
     * 用于前端检查用户是否已登录，并获取用户信息
     *
     * @return 会话状态和用户信息
     */
    @GetMapping("/check-session")
    public SaResult checkSession() {
        if (!StpUtil.isLogin()) {
            return SaResult.error("未登录");
        }

        Long userId = StpUtil.getLoginIdAsLong();
        User user = userMapper.selectById(userId);

        if (user == null) {
            return SaResult.error("用户不存在");
        }

        UserVO userVO = new UserVO();
        BeanUtils.copyProperties(user, userVO);

        return SaResult.data(userVO);
    }

    /**
     * 更新用户信息
     *
     * @param userInfo 用户信息
     * @return 更新结果
     */
    @PutMapping("/update")
    public SaResult updateUserInfo(@RequestBody Map<String, Object> userInfo) {
        if (!StpUtil.isLogin()) {
            return SaResult.error("未登录");
        }

        Long userId = StpUtil.getLoginIdAsLong();
        User user = userMapper.selectById(userId);

        if (user == null) {
            return SaResult.error("用户不存在");
        }

        // 更新用户信息
        if (userInfo.containsKey("nickname") && StringUtils.hasText(userInfo.get("nickname").toString())) {
            user.setNickname(userInfo.get("nickname").toString());
        }

        if (userInfo.containsKey("email") && StringUtils.hasText(userInfo.get("email").toString())) {
            // 检查邮箱是否已被其他用户使用
            String newEmail = userInfo.get("email").toString();
            if (!newEmail.equals(user.getEmail())) {
                LambdaQueryWrapper<User> emailWrapper = new LambdaQueryWrapper<>();
                emailWrapper.eq(User::getEmail, newEmail);
                if (userMapper.selectCount(emailWrapper) > 0) {
                    return SaResult.error("邮箱已被其他用户使用");
                }
            }
            user.setEmail(newEmail);
        }

        if (userInfo.containsKey("phone") && StringUtils.hasText(userInfo.get("phone").toString())) {
            user.setPhone(userInfo.get("phone").toString());
        }

        if (userInfo.containsKey("avatar") && StringUtils.hasText(userInfo.get("avatar").toString())) {
            user.setAvatar(userInfo.get("avatar").toString());
        }

        if (userInfo.containsKey("bio") && userInfo.get("bio") != null) {
            user.setBio(userInfo.get("bio").toString());
        }

        // 更新用户信息
        userMapper.updateById(user);

        // 返回更新后的用户信息
        UserVO userVO = new UserVO();
        BeanUtils.copyProperties(user, userVO);

        return SaResult.data(userVO);
    }

    /**
     * 修改密码
     *
     * @param passwordInfo 密码信息
     * @return 修改结果
     */
    @PutMapping("/change-password")
    public SaResult changePassword(@RequestBody Map<String, String> passwordInfo) {

        if (!passwordInfo.containsKey("oldPassword") || !passwordInfo.containsKey("newPassword")) {
            return SaResult.error("参数不完整");
        }

        String oldPassword = passwordInfo.get("oldPassword");
        String newPassword = passwordInfo.get("newPassword");

        String encryptedOldPassword = DigestUtils.md5DigestAsHex(oldPassword.getBytes(StandardCharsets.UTF_8));
        String encryptedNewPassword = DigestUtils.md5DigestAsHex(newPassword.getBytes(StandardCharsets.UTF_8));

        Long userId = StpUtil.getLoginIdAsLong();
        User user = userMapper.selectById(userId);

        if (user == null) {
            return SaResult.error("用户不存在");
        }

        // 验证旧密码
        if (!user.getPassword().equals(encryptedOldPassword)) {
            return SaResult.error("原密码错误");
        }

        // 更新密码
        user.setPassword(encryptedNewPassword);
        userMapper.updateById(user);

        return SaResult.ok("密码修改成功");
    }

    /**
     * 设置头像
     *
     * @param imageUrl 头像Url
     * @return 修改结果
     */
    @PutMapping("/set-avatar")
    public SaResult setAvatar(@RequestParam String imageUrl) {
        if (!StpUtil.isLogin()) {
            return SaResult.error("未登录");
        }
        
        Long userId = StpUtil.getLoginIdAsLong();
        User user = userMapper.selectById(userId);
        
        if (user == null) {
            return SaResult.error("用户不存在");
        }
        
        user.setAvatar(imageUrl);
        
        if (userMapper.updateById(user) > 0) {
            // 转换为VO对象，不返回敏感信息
            UserVO userVO = new UserVO();
            BeanUtils.copyProperties(user, userVO);
            return SaResult.data(userVO);
        } else {
            return SaResult.error("头像修改失败");
        }
    }
    
    /**
     * 关注用户
     *
     * @param userId 被关注的用户ID
     * @return 操作结果
     */
    @PostMapping("/follow/{userId}")
    public Response<Boolean> followUser(@PathVariable Long userId) {
        // 获取当前登录用户ID
        Long currentUserId = StpUtil.getLoginIdAsLong();
        
        // 不能关注自己
        if (currentUserId.equals(userId)) {
            return Response.error("不能关注自己");
        }
        
        // 检查被关注用户是否存在
        User followingUser = userMapper.selectById(userId);
        if (followingUser == null) {
            return Response.error("用户不存在");
        }
        
        // 检查是否已关注
        LambdaQueryWrapper<UserFollow> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(UserFollow::getFollowerId, currentUserId)
                .eq(UserFollow::getFollowingId, userId);
        UserFollow existingFollow = userFollowMapper.selectOne(queryWrapper);
        
        if (existingFollow != null) {
            // 已关注，返回成功
            return Response.success(true);
        }
        
        // 创建关注关系
        UserFollow userFollow = new UserFollow();
        userFollow.setFollowerId(currentUserId);
        userFollow.setFollowingId(userId);
        userFollowMapper.insert(userFollow);
        
        return Response.success(true);
    }
    
    /**
     * 取消关注用户
     *
     * @param userId 被取消关注的用户ID
     * @return 操作结果
     */
    @DeleteMapping("/unfollow/{userId}")
    public Response<Boolean> unfollowUser(@PathVariable Long userId) {
        // 获取当前登录用户ID
        Long currentUserId = StpUtil.getLoginIdAsLong();
        
        // 检查关注关系是否存在
        LambdaQueryWrapper<UserFollow> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(UserFollow::getFollowerId, currentUserId)
                .eq(UserFollow::getFollowingId, userId);
        UserFollow existingFollow = userFollowMapper.selectOne(queryWrapper);
        
        if (existingFollow == null) {
            // 未关注，返回成功
            return Response.success(true);
        }
        
        // 删除关注关系
        userFollowMapper.delete(queryWrapper);
        
        return Response.success(true);
    }
    
    /**
     * 获取当前用户的关注列表
     *
     * @param current 当前页
     * @param size 每页大小
     * @return 关注用户列表
     */
    @GetMapping("/followings")
    public Response<Page<UserVO>> getFollowings(
            @RequestParam(defaultValue = "1") Integer current,
            @RequestParam(defaultValue = "10") Integer size) {
        // 获取当前登录用户ID
        Long currentUserId = StpUtil.getLoginIdAsLong();
        
        // 分页查询关注列表
        Page<UserFollow> page = new Page<>(current, size);
        LambdaQueryWrapper<UserFollow> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(UserFollow::getFollowerId, currentUserId);
        Page<UserFollow> followPage = userFollowMapper.selectPage(page, queryWrapper);
        
        // 转换为用户VO列表
        Page<UserVO> userVOPage = new Page<>(current, size, followPage.getTotal());
        List<UserVO> userVOList = followPage.getRecords().stream().map(follow -> {
            User user = userMapper.selectById(follow.getFollowingId());
            UserVO userVO = new UserVO();
            if (user != null) {
                BeanUtils.copyProperties(user, userVO);
            }
            return userVO;
        }).collect(Collectors.toList());
        
        userVOPage.setRecords(userVOList);
        return Response.success(userVOPage);
    }
    
    /**
     * 获取当前用户的粉丝列表
     *
     * @param current 当前页
     * @param size 每页大小
     * @return 粉丝用户列表
     */
    @GetMapping("/followers")
    public Response<Page<UserVO>> getFollowers(
            @RequestParam(defaultValue = "1") Integer current,
            @RequestParam(defaultValue = "10") Integer size) {
        // 获取当前登录用户ID
        Long currentUserId = StpUtil.getLoginIdAsLong();
        
        // 分页查询粉丝列表
        Page<UserFollow> page = new Page<>(current, size);
        LambdaQueryWrapper<UserFollow> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(UserFollow::getFollowingId, currentUserId);
        Page<UserFollow> followerPage = userFollowMapper.selectPage(page, queryWrapper);
        
        // 转换为用户VO列表
        Page<UserVO> userVOPage = new Page<>(current, size, followerPage.getTotal());
        List<UserVO> userVOList = followerPage.getRecords().stream().map(follow -> {
            User user = userMapper.selectById(follow.getFollowerId());
            UserVO userVO = new UserVO();
            if (user != null) {
                BeanUtils.copyProperties(user, userVO);
            }
            return userVO;
        }).collect(Collectors.toList());
        
        userVOPage.setRecords(userVOList);
        return Response.success(userVOPage);
    }
    
    /**
     * 获取当前用户的收藏列表
     *
     * @param current 当前页
     * @param size 每页大小
     * @return 收藏作品列表
     */
    @GetMapping("/favorites")
    public Response<Page<ForumArtworkCardVO>> getFavorites(
            @RequestParam(defaultValue = "1") Integer current,
            @RequestParam(defaultValue = "10") Integer size) {
        // 获取当前登录用户ID
        Long currentUserId = StpUtil.getLoginIdAsLong();
        
        // 分页查询收藏列表
        Page<ArtworkFavorite> page = new Page<>(current, size);
        LambdaQueryWrapper<ArtworkFavorite> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(ArtworkFavorite::getUserId, currentUserId.toString());
        Page<ArtworkFavorite> favoritePage = artworkFavoriteMapper.selectPage(page, queryWrapper);
        
        // 转换为作品VO列表
        Page<ForumArtworkCardVO> artworkVOPage = new Page<>(current, size, favoritePage.getTotal());
        List<ForumArtworkCardVO> artworkVOList = favoritePage.getRecords().stream().map(artworkFavorite -> {
            ForumArtworkCardVO vo = new ForumArtworkCardVO();
            Artwork artwork = artworkService.getById(artworkFavorite.getArtworkId());

            BeanUtils.copyProperties(artwork, vo);

            vo.setUsername(userService.getById(artwork.getUserId()).getUsername());
            return vo;
        }).collect(Collectors.toList());
        
        artworkVOPage.setRecords(artworkVOList);
        return Response.success(artworkVOPage);
    }
    
    /**
     * 检查是否关注了指定用户
     *
     * @param userId 被检查的用户ID
     * @return 是否已关注
     */
    @GetMapping("/is-following/{userId}")
    public Response<Boolean> isFollowing(@PathVariable Long userId) {
        // 获取当前登录用户ID
        Long currentUserId = StpUtil.getLoginIdAsLong();
        
        // 检查关注关系是否存在
        LambdaQueryWrapper<UserFollow> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(UserFollow::getFollowerId, currentUserId)
                .eq(UserFollow::getFollowingId, userId);
        UserFollow existingFollow = userFollowMapper.selectOne(queryWrapper);
        
        return Response.success(existingFollow != null);
    }
    
    /**
     * 获取用户个人资料和作品列表
     * 合并了用户信息和作品列表的接口，减少前端请求次数
     *
     * @param userId 用户ID
     * @param current 当前页码
     * @param size 每页大小
     * @return 用户个人资料和作品列表
     */
    @SaIgnore
    @GetMapping("/profile/{userId}")
    public Response<UserProfileWithWorksVO> getUserProfileWithWorks(
            @PathVariable Long userId,
            @RequestParam(defaultValue = "1") Integer current,
            @RequestParam(defaultValue = "12") Integer size) {
        
        // 创建返回对象
        UserProfileWithWorksVO result = new UserProfileWithWorksVO();
        
        // 1. 获取用户基本信息
        User user = userMapper.selectById(userId);
        if (user == null) {
            return Response.error("用户不存在");
        }
        
        // 转换为VO对象
        UserVO userVO = new UserVO();
        BeanUtils.copyProperties(user, userVO);
        result.setUserInfo(userVO);
        
        // 2. 获取用户作品列表
        Page<Artwork> artworkPage = new Page<>(current, size);
        LambdaQueryWrapper<Artwork> artworkQueryWrapper = new LambdaQueryWrapper<>();
        artworkQueryWrapper.eq(Artwork::getUserId, userId)
                .eq(Artwork::getStatus, 2) // 只查询已发布的作品
                .orderByDesc(Artwork::getCreateTime);
        
        Page<Artwork> artworks = artworkMapper.selectPage(artworkPage, artworkQueryWrapper);
        
        // 转换为VO对象
        Page<ForumArtworkCardVO> artworkVOPage = new Page<>();
        BeanUtils.copyProperties(artworks, artworkVOPage, "records");
        
        List<ForumArtworkCardVO> artworkVOList = artworks.getRecords().stream().map(artwork -> {
            ForumArtworkCardVO vo = new ForumArtworkCardVO();
            BeanUtils.copyProperties(artwork, vo);
            vo.setLikeCount(artworkService.getLikeCount(artwork.getId()));
            vo.setUsername(user.getUsername());
            return vo;
        }).collect(Collectors.toList());
        
        artworkVOPage.setRecords(artworkVOList);
        result.setWorks(artworkVOPage);
        
        // 3. 获取关注状态（如果当前用户已登录）
        try {
            if (StpUtil.isLogin()) {
                Long currentUserId = StpUtil.getLoginIdAsLong();
                if (!currentUserId.equals(userId)) {
                    // 检查是否已关注
                    LambdaQueryWrapper<UserFollow> followQueryWrapper = new LambdaQueryWrapper<>();
                    followQueryWrapper.eq(UserFollow::getFollowerId, currentUserId)
                            .eq(UserFollow::getFollowingId, userId);
                    UserFollow existingFollow = userFollowMapper.selectOne(followQueryWrapper);
                    result.setIsFollowing(existingFollow != null);
                } else {
                    result.setIsFollowing(false); // 不能关注自己
                }
            } else {
                result.setIsFollowing(false); // 未登录状态
            }
        } catch (Exception e) {
            result.setIsFollowing(false); // 出现异常，默认为未关注
        }
        
        // 4. 获取统计数据
        // 关注数量
        LambdaQueryWrapper<UserFollow> followingsQueryWrapper = new LambdaQueryWrapper<>();
        followingsQueryWrapper.eq(UserFollow::getFollowerId, userId);
        int followingsCount = userFollowMapper.selectCount(followingsQueryWrapper).intValue();
        result.setFollowingsCount(followingsCount);
        
        // 粉丝数量
        LambdaQueryWrapper<UserFollow> followersQueryWrapper = new LambdaQueryWrapper<>();
        followersQueryWrapper.eq(UserFollow::getFollowingId, userId);
        int followersCount = userFollowMapper.selectCount(followersQueryWrapper).intValue();
        result.setFollowersCount(followersCount);
        
        // 作品数量
        LambdaQueryWrapper<Artwork> worksQueryWrapper = new LambdaQueryWrapper<>();
        worksQueryWrapper.eq(Artwork::getUserId, userId)
                .eq(Artwork::getStatus, 2); // 只统计已发布的作品
        int worksCount = artworkMapper.selectCount(worksQueryWrapper).intValue();
        result.setWorksCount(worksCount);
        
        return Response.success(result);
    }
}